#ifndef COMMON_H_
#define COMMON_H_

#include <stddef.h>
#define MAXSIZE 2048    /*定义数据缓冲区大小*/
#define MAXTHREAD  1       /*定义最大生产者线程数*/
#define MAXFDPERTHREAD 10   /*每个线程最大处理客户端数量*/

#define USERLIST "usr.csv"
#define GOODSLIST "goods.list" // 自定义的二进制文件，以Goods结构体的形式存储
#define TRADELOG "trade.log"   // 自定义的二进制文件

#define MAXWORKER 5     /*最大消费者工作线程数*/
#define NAME_SIZE 64    /*商品名最大长度*/
#define DESCRIPTION_SIZE (MAXSIZE - NAME_SIZE - sizeof(size_t) - 3 * sizeof(int) - sizeof(CommandType)) /*商品描述最大长度*/
#define MAX_DATA (MAXSIZE -  sizeof(Err) - sizeof(CommandType) - 2 * sizeof(int)) /*返回值的数据缓冲区长度*/

typedef enum CommandType {
    NIL,
    LOGIN,      // log in
    BUY,        // buy goods
    SELL,       // sell goods
    VIEW,       // view goods' description
    LIST,       // list all goods' IDs and names
    RECORDS,    // request user trade records
    QUIT,       // quit, handled by the threadpool
} CommandType;

typedef enum Err {
    SUCCESS,        // execute cmd success
    ERRNOTFOUND,    // goods not found
    ERRNOTLOGGEDIN, // user hasn's logged in
    ERRZERO,        // no storage
} Err;

/* user structure
* - saved in the user.
*/
typedef struct {
    /* User ID
     * - the only identifer of user.
     * - incremental
     */
    int id ;
    char name[NAME_SIZE];
    int total_buy;
    int total_sell;
} User;

typedef struct {
    int buyer_id;
    int seller_id;
    int goods_id;
    int number;
    int total_price;
} Trade;

/*      Goods structure
*  -    saved in the file
*/
typedef struct {
    
    /* Goods ID
    * - the only identifer of goods.
    * - automatically allocated by the platform. Don's assign it by yourself
    * - incremental, never reused even storage become zero
    */
    size_t id;  
    /* Goods PRICE
    *- must be non-negative
    */
    int price;
    /* Goods STORAGE
    *- must be non-negative
    */
    int storage;
    /* Owner's ID */
    int owner_id; 
    /* Aligned to MAXSIZE */ 
    char padding[4];
    /*  Goods NAME
    *- max length: 64
    */
    char name[NAME_SIZE];
    /*  Goods DESCRIPTION */
    char description[DESCRIPTION_SIZE];
} Goods;

/* Command structure
*- transmitted through socket
*/
typedef struct {
    size_t price;
    CommandType type;
    int user_id;   // when user hasn't logged in, this is empty
    int good_id;
    int number; // number to buy / sell
    char name[NAME_SIZE];
    char description[DESCRIPTION_SIZE];
} Command;

typedef struct {
    Err err;
    CommandType type;
    int user_id;        // if type is LOGIN, platform return user id
    int total_price;    // if type is BUY, platform returb total price
    char data[MAX_DATA];    /* if type is VIEW, return destription of goods
                               if type is LIST, return list of goods id, name, seller and storage*/
} Reply;                // if type is SELL, return nothing

typedef struct {
    int client_fd;
    Command cmd;
} Request;

#endif